/**
 * Copyright 2006 Bosco Curtu
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * 
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. 
 * 
 * See the License for the specific language governing permissions and limitations 
 * under the License.
*/
package com.bcurtu.db;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.jdbc.object.SqlUpdate;
import org.springframework.jdbc.object.UpdatableSqlQuery;

/**
 * @deprecated
 * @author bcm
 *
 */
public class AccountDaoJdbc extends JdbcDaoSupport implements AccountDao{

//	private ActiveAccountsQuery activeAccountsQuery;
	private BlockingAccountsQuery blockingAccountsQuery;
	private ExistingAccountsQuery existingAccountsQuery;
	private AccountInsert accountInsert;
	private AccountUpdate accountUpdate;
	private AccountDelete accountDelete;
	private AccountForceDelete accountForceDelete;
	
//	private class ActiveAccountsQuery extends MappingSqlQuery{
//		
//		protected ActiveAccountsQuery(DataSource ds){
//			super(ds,"SELECT * FROM ACCOUNTS WHERE active=True");
//		}
//
//		@Override
//		protected Object mapRow(ResultSet rs, int arg1) throws SQLException {
//			Account acc=new Account();
//			acc.setAlias(rs.getString("alias"));
//			acc.setForward(rs.getString("forward"));
//			acc.setActive(rs.getBoolean("active"));
//			acc.setBlockingDate(rs.getTimestamp("blockingDate"));
//			acc.setExpirationDate(rs.getTimestamp("expirationDate"));
//			return acc;
//		}
//		
//	}

	private class BlockingAccountsQuery extends MappingSqlQuery{
		
		protected BlockingAccountsQuery(DataSource ds){
			super(ds,"SELECT * FROM ACCOUNTS WHERE active=True AND blockingDate<=?");
			super.declareParameter(new SqlParameter(Types.TIMESTAMP));
			compile();
		}

		@Override
		protected Object mapRow(ResultSet rs, int arg1) throws SQLException {
			Account acc=new Account();
			acc.setAlias(rs.getString("alias"));
			acc.setForward(rs.getString("forward"));
			acc.setActive(rs.getBoolean("active"));
			acc.setBlockingDate(rs.getTimestamp("blockingDate"));
			acc.setExpirationDate(rs.getTimestamp("expirationDate"));
			return acc;
		}
		
	}

	private class ExistingAccountsQuery extends MappingSqlQuery{
		
		protected ExistingAccountsQuery(DataSource ds){
			super(ds,"SELECT * FROM ACCOUNTS WHERE alias=?");
			super.declareParameter(new SqlParameter(Types.VARCHAR));
			compile();
		}

		@Override
		protected Object mapRow(ResultSet rs, int arg1) throws SQLException {
			Account acc=new Account();
			acc.setAlias(rs.getString("alias"));
			acc.setForward(rs.getString("forward"));
			acc.setActive(rs.getBoolean("active"));
			acc.setBlockingDate(rs.getTimestamp("blockingDate"));
			acc.setExpirationDate(rs.getTimestamp("expirationDate"));
			return acc;
		}
		
	}

	private class AccountInsert extends SqlUpdate {

		protected AccountInsert(DataSource ds) {
			super(ds, "INSERT INTO ACCOUNTS VALUES(?,?,?,?,?)");
			declareParameter(new SqlParameter(Types.VARCHAR));
			declareParameter(new SqlParameter(Types.VARCHAR));
			declareParameter(new SqlParameter(Types.TIMESTAMP));
			declareParameter(new SqlParameter(Types.BOOLEAN));
			declareParameter(new SqlParameter(Types.TIMESTAMP));
			compile();
		}

		protected void insert(Account acc) {
			Object[] objs = new Object[] {
				acc.getAlias(), acc.getForward(),
				acc.getBlockingDate(), acc.getActive(), acc.getExpirationDate()};
			super.update(objs);
		}
	}
	
	private class AccountUpdate extends SqlUpdate {

		protected AccountUpdate(DataSource ds) {
			super(ds, "UPDATE ACCOUNTS SET active=False WHERE alias=?");
			declareParameter(new SqlParameter(Types.VARCHAR));
			compile();
		}

		public int update(String alias) {
			return this.update(new Object[] {alias});
		}
	}

	private class AccountDelete extends SqlUpdate {

		protected AccountDelete(DataSource ds) {
			super(ds, "DELETE FROM ACCOUNTS WHERE active=false AND expirationDate<=?");
			declareParameter(new SqlParameter(Types.TIMESTAMP));
			compile();
		}

		public int update(Date date) {
			return this.update(new Object[] {date});
		}
	}

	private class AccountForceDelete extends SqlUpdate {

		protected AccountForceDelete(DataSource ds) {
			super(ds, "DELETE FROM ACCOUNTS WHERE alias=?");
			declareParameter(new SqlParameter(Types.VARCHAR));
			compile();
		}

		public int update(String alias) {
			return this.update(new Object[] {alias});
		}
	}

	@Override
	protected void initDao() throws Exception {
//		this.activeAccountsQuery=new ActiveAccountsQuery(getDataSource());
		this.blockingAccountsQuery=new BlockingAccountsQuery(getDataSource());
		this.existingAccountsQuery=new ExistingAccountsQuery(getDataSource());
		this.accountInsert=new AccountInsert(getDataSource());
		this.accountUpdate=new AccountUpdate(getDataSource());
		this.accountDelete=new AccountDelete(getDataSource());
		this.accountForceDelete=new AccountForceDelete(getDataSource());
	}

	public boolean isValidAlias(String alias){
		List accs=existingAccountsQuery.execute(new Object[]{alias});
		return (accs==null || accs.size()==0);
	}
	
	public void insertAccount(Account acc){
		accountInsert.insert(acc);
	}
	
	public int blockAccount(String alias){
		return accountUpdate.update(alias);
	}
	
	public int deleteExpiredAccounts(Date date){
		return accountDelete.update(date);
	}

	public int forceDeleteAccount(String alias){
		return accountForceDelete.update(alias);
	}

	public List<Account> getBlockingAccounts(Date date){
		return blockingAccountsQuery.execute(new Object[]{date});
	}

	public Account getAccountByAliasAndForward(String alias, String forward) {
		// TODO Auto-generated method stub
		return null;
	}

	public void updateAccount(Account acc) {
		// TODO Auto-generated method stub
		
	}
	
	
}
